package java

import (
	"bytes"
	"flag"
	"gitee.com/yysf_xin/dplog/pkg/extracter"
	"gitee.com/yysf_xin/go-common/tools"
	"strconv"
)

var (
	// java stack
	stackTrack = []byte("\tat ")
	//casedBy = []byte("Caused by")
)

type counter struct {
	count, index, hidden int
}

func (h *counter) Rest() {
	if h.count != 0 {
		*h = counter{}
	}
}

type Opt struct {
	// 异常堆栈保存最多的条数，过滤无意义的堆栈
	MaxEl int `yaml:"max_el"`
	// 主包
	Package string   `yaml:"package"`
	Mybatis []string `yaml:"mybatis"`
}

type extract struct {
	Opt *Opt
	counter
	pkg []byte
}

func NewExtract(opt *Opt) extracter.SubLine {
	return &extract{Opt: opt, pkg: tools.StringToBytes(opt.Package)}
}

func (e *extract) SubExtract(line []byte, out *bytes.Buffer) {
	// 可能是上条消息
	if bytes.HasPrefix(line, stackTrack) {
		if e.count == e.Opt.MaxEl {
			if bytes.HasPrefix(line[len(stackTrack):], e.pkg) {
				e.count = 0
			} else {
				e.hidden++
				return
			}
		} else {
			e.count++
		}
	}
	if e.hidden != 0 {
		out.WriteString("\n...")
		out.WriteString(strconv.Itoa(e.hidden))
		e.hidden = 0
	}
	out.WriteByte('\n')
	out.Write(line)
}

func InitFlag(opt *Opt) {
	// for java
	flag.StringVar(&opt.Package, "package", "com.feng1", "java package name")
	flag.IntVar(&opt.MaxEl, "maxEl", 3, "java max stack track")
}
